<?php

/**
 * Created by Sven.
 * Date: 2016/12/26
 * Time: 15:16
 *
 * 定制Page分页类的基本步骤：
 * 1、确定总条数 total（构造函数传入）
 * 2、页容量 size
 * 3、当前页码 pagenum（需要做：1、合法性判断 2、边界判断）
 * 4、limit（需要用到 2 3）
 * 5、定制 showPage 生成的分页组件html
 *
 * 使用方法：
 * $page = new Page($_total, PAGE_SIZE, $config= array() );
 * // 可传递参数调整顺序： 0->首页  1->上一页  2->页码列表 3->下一页 4->尾页 5->跳转
 * $page->fPageHtml( array(0, 1, 2, 3, 4, 5) );
 *
 */
class Page {

    private $totalCount; // 总条数
    private $pageSize; // 每页显示条数
    private $currPage; // 当前页码
    private $totalPage; // 总页数

    private $limit = '';
    private $uri = '';
    private $config = array();
    private $bothNum = 5; // 当前页码两边个数

    private $pageArray = array();

    public function __construct( $totalCount, $num = 10, $config =
    array( 'header' => "篇文章", 'first' => '首页', 'prev' => '上一页', 'next' => '下一页', 'last' => '尾页' ) ) {
        $this->totalCount = $totalCount;
        $this->pageSize = $num;

        // 计算总页数
        $this->totalPage = ceil( $this->totalCount / $this->pageSize );

        // 设置当前页
        $this->currPage = $this->setPage();

        // 设置uri(去除page参数)
        $this->uri = $this->getUri();

        // 设置配置信息
        $this->config = $config;

        // 设置limit
        //" limit 0, 10 ";
        $_limit_start = ( $this->currPage - 1 ) * $this->pageSize;
        $_limit_start =  $_limit_start < 0 ? 0 : $_limit_start;

        $this->limit = "limit {$_limit_start}, {$this->pageSize}" ;
    }

    // 设置当前页
    private function setPage() {
        if ( isset( $_GET[ 'page' ] ) && !empty( $_GET[ 'page' ] ) ) {
            $_page = intval( $_GET[ 'page' ] );
            if ( $_page < 1 ) {
                $_page = 1;
                return $_page;
            }
            if ( $_page > $this->totalPage ) {
                $_page = $this->totalPage;
                return $_page;
            }
            return $_page;
        } else {
            $_page = 1;
            return $_page;
        }
    }

    // 设置新的Uri：1、 保证原有的数据 2、去除page
    private function getUri() {
        // /admin/main_home_manage.php?action=show&page=3
        $url = $_SERVER[ 'REQUEST_URI' ];
        // /admin/main_home_manage.php
        $basePage = $_SERVER[ 'SCRIPT_NAME' ];

        // 构建基础字符串
        $finalURL = $basePage . '?';

//        $arr => {path=>'/admin/main_home_manage.php', query=>'action=show&page=3'}
        // 解析$url
        $arr = parse_url( $url );

        // 如果有query参数
        if ( isset( $arr[ 'query' ] ) ) {
            // 则：1、解析query参数到$params数组
            parse_str( $arr[ 'query' ], $params );

            // 则：2、 删除page变量
            unset( $params[ 'page' ] );

            // 则：3、重新构建参数
            $res = http_build_query( $params );
            // 则：4、整合 $finalURL
            $finalURL .= $res;
        }
        // 返回
        return $finalURL;
    }

    // 外部获取私有属性
    public function __get( $property ) {
        if ( in_array( $property,array('limit', 'currPage') ) ) {
            return $this->$property;
        } else {
            return NULL;
        }
    }

    ////////////////// 输出主体内容 -- 开始 //////////////

    private function first() {
        $html = "共 {$this->totalCount} " . $this->config[ 'header' ];
        if ( $this->currPage > 1 ) {
            $html .= "<a class='first' href='{$this->uri}&page=1'>{$this->config['first']}</a>";
        }
        return $html;
    }

    private function firstArray() {
        if ( $this->currPage > 1 ) {
            $this->pageArray['first'] = "{$this->uri}&page=1";
        }
    }

    private function prev() {
        $html = '';
        if ( $this->currPage > 1 ) {
            $html = "<a class='prev' href='{$this->uri}&page=" . ( $this->currPage - 1 ) . "'>{$this->config['prev']}</a>";
        }

        return $html;
    }

    private function prevArray() {
        if ( $this->currPage > 1 ) {
            $this->pageArray['prev'] = "{$this->uri}&page=". ( $this->currPage - 1 ) . "";
        }
    }


    private function pageList() {
        $html = '';
        $start = max( $this->currPage - 5, 1 ); // 不能小于1
        $end = min( $this->currPage + 5, $this->totalPage ); // 不能大于$this->totalPage

        for ( $i = $start; $i <= $end; $i ++ ) {

            if ( $this->currPage == $i ) {
                $html .= $i . '&nbsp; '; // 当前页面不显示超链接
            } else {
                $html .= "<a class='num' href='$this->uri&page={$i}'>{$i}</a> &nbsp;";
            }

        }

        return $html;
    }

    public function  pageListArray(){
        $start = max( $this->currPage - $this->bothNum, 1 ); // 不能小于1
        $end = min( $this->currPage + $this->bothNum, $this->totalPage ); // 不能大于$this->totalPage

        $this->pageArray['pageList'] = array();
        for ( $i = $start; $i <= $end; $i ++ ) {

            if ( $this->currPage == $i ) {
                $this->pageArray['pageList'][$i] = '';
            } else {
                $this->pageArray['pageList'][$i] = "$this->uri&page={$i}";
            }

        }
    }

    private function next() {
        $html = '';
        if ( $this->currPage < $this->totalPage ) {
            $html = "<a class='next' href='{$this->uri}&page=" . ( $this->currPage + 1 ) . "'>{$this->config['next']}</a>";
        }
        return $html;
    }

    private function nextArray(){
        if ( $this->currPage < $this->totalPage ) {
            $this->pageArray['next'] = "{$this->uri}&page=" . ( $this->currPage + 1 ) . "";
        }
    }

    private function last() {
        $html = '';
        if ( $this->currPage < $this->totalPage ) {
            $html = "<a class='last' href='{$this->uri}&page=" . ( $this->totalPage ) . "'>{$this->config['last']}</a>";
        }
        return $html;
    }

    private function lastArray(){
        if ( $this->currPage < $this->totalPage ) {
            $html = "<a class='last' href=''>{$this->config['last']}</a>";
            $this->pageArray['last'] = "{$this->uri}&page=" . ( $this->totalPage ) . "";
        }
    }

    private function go() {
        $html = <<<EOF
        <script type="text/javascript">
            function onkeydown_func(obj, isKeyDown){
                if ( isKeyDown   ){
                    if (event.keyCode == 13){
                        var page = obj.value;
                        window.location.href = '%s&page='+page;
                    } 
                } else {
                    var input = document.getElementById('pageInput');
                    var page = input.value;
                    window.location.href = '%s&page='+page;
                }
                
            }
        </script>
        <input type="text" size="3" value='%s' id='pageInput'  onkeydown="javascript:onkeydown_func(this, true)" />
        <button  class='btnGo' onclick="javascript:onkeydown_func(this, false)">Go</button>
EOF;
        $html = sprintf( $html, $this->uri, $this->uri,  $this->currPage );

        return $html;
    }

    ////////////////// 输出主体内容 -- 结束 //////////////

    /**
     * 输出格式化的分页组件html
     * @param array $format
     * @return string
     * 格式固定，不易修改
     */
    public function fPageHtml( $format = array( 0, 1, 2, 3, 4, 5 ) ) {
        $html = array();
        $html[ 0 ] = $this->first(); // 0-> 首页
        $html[ 1 ] = $this->prev(); // 1-> 上一页
        $html[ 2 ] = $this->pageList(); // 2-> 页码列表
        $html[ 3 ] = $this->next(); // 3-> 下一页
        $html[ 4 ] = $this->last(); // 4->尾页
        $html[ 5 ] = $this->go(); // 5-> 跳转

        $fpage = '';
        foreach ( $format as $val ) {
            if ( isset( $html[ $val ] ) ) {
                $fpage .= $html[ $val ];
            }
        }

        return $fpage;
    }

    /**
     * 输出数组形式的分页组件
     * 方便在模板引擎中显示
     * @return array
     */
    public function fPageArray() {
        $this->firstArray();
        $this->prevArray();
        $this->pageListArray();
        $this->nextArray();
        $this->lastArray();
        return $this->pageArray;
    }

    // 输出最终分页html代码( toString 是默认的输出方式)
    public function __toString() {
        return $this->fPageHtml( array( 0, 1, 2, 3, 4, 5 ) );
    }

}

?>